<template>
    <el-dialog v-model="transferVisible" title="权限分配" width="800">
        <div class="transfer">
            <div class="contaner">
                <!-- 左-->
                <div class="item">
                    <div class="title">
                        已分配权限
                    </div>
                    <div class="tree">
                        <el-tree ref="treeRef" :data="transDataAuth" :props="transProps" show-checkbox />
                    </div>
                </div>
                <div class="transfercenter">
                    <!-- 中   -->
                    <div class="transbutton">
                        <el-button type="primary" :icon="ArrowLeft" @click="leftButtonClick"></el-button>
                        <el-button type="primary"><el-icon class="el-icon--right" @click="rightButtonClick">
                                <ArrowRight />
                            </el-icon></el-button>
                    </div>
                </div>
                <!-- 右  -->
                <div class="item">
                    <div class="title">
                        未分配权限
                    </div>
                    <div class="tree">
                        <el-tree ref="treeRef1" :data="transDataNoAuth" :props="transProps" show-checkbox />
                    </div>
                </div>

            </div>
            <div>
                <div class="footer">
                    <el-button type="primary" @click="onDialogFormConfirmTransfer">确 定</el-button>
                    <el-button @click="onDialogFormCancelTransFer">取 消</el-button>
                </div>
            </div>
        </div>
    </el-dialog>
</template>

<script lang="ts" setup>
import {ref } from 'vue'
import {ArrowLeft, ArrowRight  } from '@element-plus/icons-vue'

const props = defineProps<{
    transDataAuth: Array<any>,
    transDataNoAuth:  Array<any>
}>()

// 传回的菜单ids
const emit = defineEmits(['returnIds'])

const transferVisible = ref(false)
const treeRef = ref() 
const treeRef1= ref() 


const transProps = {
    id: "roleId",
    children: 'children',
    label: 'menuName',
}

// 提交对话框表单按钮事件
const onDialogFormConfirmTransfer = async () => {
    let authMenus = flattenMenuTree(props.transDataAuth)
    let ids = authMenus.map((item: any) => item.id)
    emit('returnIds', ids)
}
// 取消对话表单框按钮事件
const onDialogFormCancelTransFer = () => {
    transferVisible.value = false
}

// 授权按钮
const leftButtonClick = () => {
    let selctedMenus = treeRef1.value.getCheckedNodes(false, false)
    let ids = selctedMenus.map((item: any) => item.id)
    // 解构菜单树
    let authList = flattenMenuTree(props.transDataAuth)
    let notAuthList = flattenMenuTree(props.transDataNoAuth)
    // 添加授权，删除未授权菜单
    authList.push(...selctedMenus)
    notAuthList = notAuthList.filter(item => !ids.includes(item.id))
    // 重新构建菜单树
    transData.value = []
    transData1.value = []
    transData.value = buildMenuTree(filterRepetition(authList))
    transData1.value = buildMenuTree(filterRepetition(notAuthList))
}

// 取消授权按钮
const rightButtonClick = () => {
    let selctedMenus = treeRef.value.getCheckedNodes(false, false)
    let ids = selctedMenus.map((item: any) => item.id)
    // 解构菜单树
    let authList = flattenMenuTree(props.transDataAuth)
    let notAuthList = flattenMenuTree(props.transDataNoAuth)
    // 添加授权，删除未授权菜单
    notAuthList.push(...selctedMenus)
    authList = authList.filter(item => !ids.includes(item.id))
    // 重新构建菜单树
    transData.value = buildMenuTree(filterRepetition(authList))
    transData1.value = buildMenuTree(filterRepetition(notAuthList))
}

// 构建列表树
function buildMenuTree(menuList: any) {  
    // 创建一个映射，以便快速通过ID查找菜单项  
    const map = new Map(menuList.map((item: any) => [item.id, { ...item, children: [] }]));  
  
    // 遍历菜单列表，构建树结构  
    function attachChildren(parentId = 0) {  
        // 查找所有具有指定parentId的菜单项  
        return menuList.filter((item: any) => item.parentId === parentId).map((item: any) => {  
            const currentNode: any = map.get(item.id)
            // 递归地为当前节点附加子节点  
            currentNode.children = attachChildren(item.id)
            return currentNode;  
        });  
    }  
  
    // 注意：顶级菜单项（没有parentId或parentId为null/undefined）  
    const tree = attachChildren();  
    return tree;  
} 

function flattenMenuTree(tree: any) {  
    let result: any = [] 
    // 递归函数来遍历树并收集节点  
    function traverse(nodes: any) {  
        nodes.forEach((node: any) => {  
            // 将当前节点添加到结果数组中  
            result.push({ ...node});
            if (node.children && node.children.length > 0) {  
                traverse(node.children);
            }  
        });  
    }    
    // 开始遍历树  
    traverse(tree);  
  
    // 如果不需要层级信息，直接返回结果数组  
    return result;  
}  

// 过滤重复的菜单
const filterRepetition = (menulist: any) => {
    // console.log("menulist: " + menulist)
    let seenIds = new Set();  
    // 过滤菜单项  
    let menus = menulist.filter((item: any) => {  
        // 如果当前项的id在Set中不存在，则添加到Set中，并返回true（保留该项）  
        // 否则，返回false（移除该项）  
        if (!seenIds.has(item.id)) {  
            seenIds.add(item.id);  
            return true;  
        }  
        return false;  
    })
    //console.log("menulist: " + menulist)
    return menus
}


</script>


<style lang="scss">
.transfer {
    display: flex;
    flex-direction: column;

    .contaner {
        display: flex;
        flex-direction: row;
        justify-content: space-between;
        height: 500px;

        .item {
            display: flex;
            flex-direction: column;
            width: 40%;
            height: 100%;

            .title {
                text-align: center;
                background-color: #F5F7FA;
                height: 6%;
                font-size: 16px;

            }

            .tree {
                overflow-y: scroll;
                height: 94%;
            }
        }

        .transfercenter {
            display: flex;

            padding-top: 30px;
            box-sizing: border-box;
            width: 20%;
            height: 100%;

            // border: 10px solid black; /* 边框宽度、样式、颜色 */
            // background-color: #FF0000;
            .transbutton {
                margin-top: 200px;
            }

        }


    }

    .footer {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
    }
}
</style>